// constructing atomics
#include <iostream>       // std::cout
#include <atomic>         // std::atomic, std::atomic_flag, ATOMIC_FLAG_INIT
#include <thread>         // std::thread, std::this_thread::yield
#include <vector>         // std::vector

/// 一个全局变量，确保每个线程读到的都是相同的值。不会出现争抢(data race)
std::atomic<bool> ready (false);
/// 内存锁，一个跨越全部线程的状态设置和检查。
std::atomic_flag winner = ATOMIC_FLAG_INIT;

void count1m (int id)
{
    /// 等待ready变化。一旦 ready 变化，所有线程会同步收到。
    while (!ready)
    {
	/// 没有变化前一直发呆。
	std::this_thread::yield();
    }
    /// 海量的空循环有可能被先进的编译器优化... 加 volatile 关键字禁止
    /// 编译器优化这个变量的操作。
    for (volatile int i=0; i<1000000; ++i) {}  // go!, count to 1 million
    /// 先 test 再 set，只有第一个触碰的线程会是 false，之后就是 true.
    /// 所以 atomic_flag 追求的是诸线程的异步。
    if (!winner.test_and_set())
    {
	std::cout << "thread #" << id << " won!\n";
    }
};

int main ()
{
    std::vector<std::thread> threads;
    std::cout << "spawning 10 threads that count to 1 million...\n";
    for (int i=1; i<=10; ++i)
	threads.push_back(std::thread(count1m,i));
    /// 发出开始指令。
    ready = true;
    /// c++ 版的 for-each ...
    for (auto& th : threads)
	th.join();

    return 0;
}
